msroute: Try to detect records instead of calculating various (unknown) header lengths.
authoroliskoli <oliskoli>
Fri, 18 Apr 2008 22:00:46 +0000 (22:00 +0000)
committeroliskoli <oliskoli>
Fri, 18 Apr 2008 22:00:46 +0000 (22:00 +0000)
msroute.c

index 754172b5032a4aad7b9398e6de0e0c27ae8a1c86..c3fb767c49c225a1b8880f533dbf3869344c1763 100644 (file)
--- a/msroute.c
+++ b/msroute.c
@@ -2,7 +2,7 @@
 
        Support for Microsoft AutoRoute 2002 ".axe" files,
        
-       Copyright (C) 2005,2007 Olaf Klein, o.b.klein@gpsbabel.org
+       Copyright (C) 2005,2007,2008 Olaf Klein, o.b.klein@gpsbabel.org
 
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
@@ -566,17 +566,15 @@ ole_deinit(void)
 static void
 msroute_read_journey(void)
 {
-       int len;
+       int bufsz;
        char *buff;
        
-       buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &len);
+       buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &bufsz);
                        
-       if ((buff != NULL) && (len > 0))
+       if ((buff != NULL) && (bufsz > 0))
        {
                msroute_head_t *head = (msroute_head_t *)buff;
-               char *cin;
-               int len;
-               char text[256];
+               unsigned char *cin, *cend;
                int count = 0;
                route_head *route;
                waypoint *wpt;
@@ -587,7 +585,8 @@ msroute_read_journey(void)
                version = buff[0x14];
                is_fatal((version < 1) || (version > 7), MYNAME ": Unsupported version %d!", version);
 
-               cin = buff + 71; // sizeof(msroute_head_t);
+               cin = (unsigned char *)buff + 71; // (at least?) sizeof(msroute_head_t);
+               cend = (unsigned char *)buff + bufsz;
                        
                route = route_head_alloc();
                route_add_head(route);
@@ -596,47 +595,51 @@ msroute_read_journey(void)
                
                while (count < head->waypts)
                {
-                       double lat, lon;
-                       short test;
+                       int len;
                                
-                       cin++;
-                       if (version == 7) cin+=8;
+                       /* after version 6 we've seen data with different header length */
+                       /* now we try to find the next pair of names in buff */
+
+                       while (1) {
+                               len = *cin;
+                               if ((cin + 120) > cend) {
+                                       cin = NULL;
+                                       break;
+                               }
+                               if ((cin + len < cend) &&       /* within buff ? */
+                                   (cin[len + 3] == 0xff) &&   /* 0xff before next length byte ? */
+                                   (cin[len + 4] == len) &&    /* wide string of same length ? */
+                                   (le_read16(cin + len + 1) == 0xfeff)) {
+                                       break;
+                               }
+                               cin++;
+                       }
+                       if (cin == NULL) break;
                        
-                       len = *cin++;
-                       strncpy(text, cin, len);
-                       text[len] = '\0';
+                       wpt = waypt_new();
 
-                       cin += len + 1;
-                       test = le_read16(cin);
-                       is_fatal((test != -2), MYNAME ": Unsupported byte order within data (%d).", test);
-                       
-                       cin += 2;
+                       len = *cin++;                   /* length of shortname */
+                       cin += len;
+                       cin += 3;                       /* 0xfffeff */
                        
-                       len = *cin;                     /* skip wide-string 'name' */
-                       cin += (len * 2) + 1;
-                               
+                       len = *cin++;
+                       wpt->shortname = cet_str_uni_to_utf8((const short *)cin, len);
+                       cin += (len * 2);               /* seek over wide string */
                        cin += (5 * sizeof(gbint32));   /* five unknown DWORDs */
                                
                        /* offs 12 !!!! Latitude int32 LE       */
                        /* offs 16 !!!! Longitude int32 LE      */
-                               
-                       lat = GPS_Math_Semi_To_Deg(le_read32(cin+12));
-                       lon = GPS_Math_Semi_To_Deg(le_read32(cin+16));
+                       wpt->latitude = GPS_Math_Semi_To_Deg(le_read32(cin+12));
+                       wpt->longitude = GPS_Math_Semi_To_Deg(le_read32(cin+16));
 
                        cin += (23 * sizeof(gbint32));
                        cin += 3;
-
-                       count++;
-                               
-                       wpt = waypt_new();
-                               
-                       wpt->latitude = lat;
-                       wpt->longitude = lon;
-                       wpt->shortname = xstrdup(text);
+                       
 #ifdef OLE_DEBUG
                        waypt_add(waypt_dupe(wpt));     /* put to wpt-list to see results if no output is specified */
 #endif                         
                        route_add_wpt(route, wpt);
+                       count++;
                }
        }
        
@@ -676,5 +679,5 @@ ff_vecs_t msroute_vecs = {
        NULL,
        NULL, 
        msroute_args,
-       CET_CHARSET_MS_ANSI, 1          /* CET-REVIEW */
+       CET_CHARSET_UTF8, 1             /* CET-REVIEW */
 };